#include "stdafx.h"
#include "CVSequence.h"
#include <iostream>
using namespace std;
CVSequence::CVSequence():
m_seq(0)
{
}
CVSequence::CVSequence(const VCOPTR &seq): m_seq(0)
{
	copy(seq);
 }
CVSequence::CVSequence(const CVSequence &seq):
 m_seq(0)
{
	copy(*(seq.m_seq));
}

void CVSequence::copy(const VCOPTR &rhs)
{
	m_seq = new VCOPTR();
	// copy process
	for ( VCOIter _iter = rhs.begin();
			_iter != rhs.end(); 
			++_iter)
	{
		m_seq->push_back( 
			(*_iter)->clone() 
			);
	}
}
void CVSequence::destroy()
{
	if ( m_seq )
	{
		// the loop below can be replace by the generic algorithm "forall" and a function
		// object that can delete the pointers contained in the container.
		for ( VCOIter _iter = m_seq->begin();
				_iter != m_seq->end();
				++_iter)
		{
			delete (*_iter);
		}
		delete m_seq;
		m_seq = 0;
	}
}
CVSequence::~CVSequence()
{
	destroy();
}
CVSequence& CVSequence::operator = ( const CVSequence &rhs)
{
	if ( this != &rhs )
	{
		if (m_seq != 0)
			destroy();
        copy(*(rhs.m_seq));
	}
	return *this;
}
const size_t CVSequence::number() const
{
	if ( m_seq->empty() )
		return 0;
	else
        return m_seq->size();
}
void CVSequence::number(const size_t &num)
{
	if ( m_seq )
	{
		destroy();
		nAssign(num);
	}
	else
	{
		nAssign(num);
	}
}
void CVSequence::add(const CompositeVent &item)
{
	if ( !m_seq ) m_seq = new VCOPTR();
	m_seq->push_back(
		item.clone()
		);
}
void CVSequence::nAssign(const size_t &num)
{
	if (!m_seq) 
	{
		m_seq = new VCOPTR();
	}
	for ( size_t i = 0; i < num; ++i)
	{
		m_seq->push_back(
			new CompositeVent()
		);
	}
}

// This function must be carefully inspected.
// To check the correctness of the parameters assignment
bool CVSequence::parameters(const vector<double> &paras)
{	
	if ( paras.empty() ) return false;
	if ( paras.size() != 2*number() ) return false;
	vector<double>::const_iterator first = paras.begin(), second= paras.begin();
	++second;
	VCOIter iter = m_seq->begin();

	for (unsigned int i = 0; i != number(); ++i)
	{
		(*iter)->VentCoe(*first);
		(*iter)->sill(*second);
		/********************************************
		The access order is revised at 25/10/2007 (dd/mm/yyyy)
		********************************************/
		if ( i != (number() -1) )
		{
			++(++first);
			++(++second);
			++ iter;
		}
	}
	return true;
}
vector<double> CVSequence::parameters() const
{
	vector<double> tmp;
	tmp.clear();
	for (VCOIter iter = m_seq->begin();
			iter != m_seq->end();
			++ iter)
	{
		tmp.push_back(
			(*iter)->VentCoe()
			);
		tmp.push_back(
			(*iter)->sill()
			);
	}
	return tmp;
}
double CVSequence::output(const double &sill) const
{
	return calc(sill);
}
double CVSequence::calc(const double &SillNCU) const
{
	double output = 0;
	for (VCOIter iter = m_seq->begin();
			iter != m_seq->end();
			++ iter)
	{
		output += (*iter)->output(SillNCU);
	}
	return output;
}

CVSequence* CVSequence::clone() const
{
	return new CVSequence(*this);
}
bool CVSequence::initialize(const vector<double> &paras)
{
	if ((paras.size() % 2)) return false;
	number(paras.size()/2);
	parameters(paras);
	return true;
}